package com.tfc.glassesfree3dplayer;

import static com.tfc.glassesfree3dplayer.MainActivity.TAG;
import static com.tfc.glassesfree3dplayer.MainActivity.videoPath;

import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.media3.common.MediaItem;
import androidx.media3.exoplayer.ExoPlayer;
import androidx.media3.ui.PlayerView;

import com.google.gson.Gson;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.ArrayList;


class VideoResponse {
    private int code;
    private String msg;
    private VideoData data;

    // getters and setters
    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public VideoData getData() {
        return data;
    }

    public void setData(VideoData data) {
        this.data = data;
    }
}

class VideoData {
    private String video_url;
    public String getVideoUrl() {
        return video_url;
    }
}

class LiveResponse {
    private int code;
    private String msg;
    private String title;
    private String pic;
    private String player;
    private Map<String, String> urls; // 使用 Map 存储不同清晰度的 URL

    // Getter 和 Setter 方法
    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getPic() {
        return pic;
    }

    public void setPic(String pic) {
        this.pic = pic;
    }

    public String getPlayer() {
        return player;
    }

    public void setPlayer(String player) {
        this.player = player;
    }

    public Map<String, String> getUrls() {
        return urls;
    }

    public void setUrls(Map<String, String> urls) {
        this.urls = urls;
    }

    @Override
    public String toString() {
        return "LiveInfo{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                ", title='" + title + '\'' +
                ", pic='" + pic + '\'' +
                ", player='" + player + '\'' +
                ", urls=" + urls +
                '}';
    }
}

public class DouyinVideo extends AppCompatActivity {
    private ExoPlayer player;
    private PlayerView playerView;
    public String douyinVideoLink;
    public TextView extractLink;
    public TextView resolveLink;
    EditText customizeWebVideoSourceEditText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_douyin_video);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.douyin_video), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        playerView = findViewById(R.id.player_view);
        Button douyinButton = findViewById(R.id.douyin_source_button);
        Button customizeWebVideoSourceButton = findViewById(R.id.customize_web_video_source_button);
        customizeWebVideoSourceEditText = findViewById(R.id.customize_web_video_source_edit_text);
        extractLink = findViewById(R.id.extract_link);
        resolveLink = findViewById(R.id.resolve_link);

        // 初始化ExoPlayer
        player = new ExoPlayer.Builder(this).build();
        playerView.setPlayer(player);

        douyinButton.setOnClickListener(v -> {
            extractLink.setText("https://v.douyin.com/hme8Cs8JTL0/");
            resolveLink.setText("");
            getDouyinVideoUri("https://v.douyin.com/hme8Cs8JTL0/");
        });

        customizeWebVideoSourceButton.setOnClickListener(v -> {
            extractLink.setText("");
            resolveLink.setText("");
            String originalText = customizeWebVideoSourceEditText.getText().toString();
            List<String> videoLinks = extractLinks(originalText);
            Log.d(TAG, "提取到的链接:" + videoLinks);
            for (String videoLink : videoLinks) {
                Log.d(TAG, "链接：" + videoLink);
                extractLink.setText(videoLink);
                // 获取抖音视频流地址
                getDouyinVideoUri(videoLink);
            }
        });
    }

    private void getDouyinVideoUri(String videoAddress) {
        if(videoAddress.contains("live.douyin.com")){
            //获取抖音直播地址
            //获取直播id
            String id = String.valueOf(extractLastNumberFromUrl(videoAddress));
            ApiClient apiClient = new ApiClient();
            apiClient.getDataFromApi("https://api.ilingku.com/int/v1/douyinlive?id=" + id, new ApiClient.ApiCallback() {
                @Override
                public void onSuccess(String response) {
                    // 在主线程更新UI
                    runOnUiThread(() -> {
                        try {
                            // 解析JSON响应
                            JSONObject jsonObject = new JSONObject(response);
                            Log.d(TAG, "视频链接解析结果：" + jsonObject);

                            Gson gson = new Gson();
                            LiveResponse apiResponse = gson.fromJson(response, LiveResponse.class);
                            douyinVideoLink = "https:" + apiResponse.getUrls().get("FULL_HD1");
                            Log.d(TAG, "视频链接：" + douyinVideoLink);
                            Toast.makeText(DouyinVideo.this, "视频解析成功！", Toast.LENGTH_SHORT).show();
                            resolveLink.setText(douyinVideoLink);
                            //播放视频
                            MediaItem mediaItem = MediaItem.fromUri(douyinVideoLink);
                            // 设置MediaItem并准备播放
                            player.setMediaItem(mediaItem);
                            player.prepare();
                            player.play();

                            //视频播放成功，清空输入框
                            customizeWebVideoSourceEditText.setText("");
                        } catch (Exception e) {
                            Toast.makeText(DouyinVideo.this, "视频解析失败", Toast.LENGTH_SHORT).show();
                            Log.d(TAG, "发生错误：" + e);
                        }
                    });
                }

                @Override
                public void onFailure(Exception e) {
                    Log.d(TAG, "发生错误：" + e);
                    runOnUiThread(() -> {
                        // 显示错误
                        Toast.makeText(DouyinVideo.this, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                    });
                }
            });
        }else if(videoAddress.contains("v.douyin.com")){
            //获取抖音短视频地址
            ApiClient apiClient = new ApiClient();
            apiClient.getDataFromApi("https://api.xinyew.cn/api/douyinjx?url=" + videoAddress, new ApiClient.ApiCallback() {
                @Override
                public void onSuccess(String response) {
                    // 在主线程更新UI
                    runOnUiThread(() -> {
                        try {
                            // 解析JSON响应
                            JSONObject jsonObject = new JSONObject(response);
                            Log.d(TAG, "视频链接解析结果：" + jsonObject);

                            Gson gson = new Gson();
                            VideoResponse apiResponse = gson.fromJson(response, VideoResponse.class);
                            douyinVideoLink = apiResponse.getData().getVideoUrl();
                            Log.d(TAG, "视频链接：" + douyinVideoLink);
                            resolveLink.setText(douyinVideoLink);
                            Toast.makeText(DouyinVideo.this, "视频解析成功！", Toast.LENGTH_SHORT).show();
                            //播放视频
                            MediaItem mediaItem = MediaItem.fromUri(douyinVideoLink);
                            // 设置MediaItem并准备播放
                            player.setMediaItem(mediaItem);
                            player.prepare();
                            player.play();

                            //视频播放成功，清空输入框
                            customizeWebVideoSourceEditText.setText("");
                        } catch (Exception e) {
                            Toast.makeText(DouyinVideo.this, "视频解析失败，请检查链接", Toast.LENGTH_SHORT).show();
                            Log.d(TAG, "发生错误：" + e);
                        }
                    });
                }

                @Override
                public void onFailure(Exception e) {
                    Log.d(TAG, "发生错误：" + e);
                    runOnUiThread(() -> {
                        // 显示错误
                        Toast.makeText(DouyinVideo.this, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
                    });
                }
            });
        }else{
            //在主线程播放
            runOnUiThread(() -> {
                // 设置视频流的URI
                Uri videoUri = Uri.parse(videoAddress);
                MediaItem mediaItem = MediaItem.fromUri(videoUri);
                // 设置MediaItem并准备播放
                player.setMediaItem(mediaItem);
                player.prepare();
                player.play();
            });
        }
    }

    //获取重定向后最终的链接
    public static String getFinalUrl(String url) throws IOException {
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        connection.setInstanceFollowRedirects(false); // 禁止自动重定向
        connection.connect();

        int responseCode = connection.getResponseCode();
        if (responseCode >= 300 && responseCode < 400) {
            String redirectUrl = connection.getHeaderField("Location");
            if (redirectUrl != null) {
                // 处理相对路径重定向
                if (redirectUrl.startsWith("/")) {
                    URL original = new URL(url);
                    redirectUrl = original.getProtocol() + "://" + original.getHost() + redirectUrl;
                }
                return getFinalUrl(redirectUrl); // 递归处理多重重定向
            }
        }
        return url;
    }

    //提取链接
    public static List<String> extractLinks(String text) {
        List<String> links = new ArrayList<>();

        // 正则表达式匹配常见的URL格式
        String regex = "(https?://|www\\.)[\\w-]+(\\.[\\w-]+)+([\\w-.,@?^=%&:/~+#]*[\\w@?^=%&/~+#])?";

        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text);

        while (matcher.find()) {
            String url = matcher.group();
            // 如果是以www.开头但没有http://前缀，则添加http://
            if (url.startsWith("www.")) {
                url = "http://" + url;
            }
            links.add(url);
        }
        return links;
    }

    //提取链接中最后的数字
    public static Long extractLastNumberFromUrl(String url) {
        if (url == null || url.isEmpty()) {
            return null;
        }

        Pattern pattern = Pattern.compile("(\\d+)(?!.*\\d)");
        Matcher matcher = pattern.matcher(url);

        if (matcher.find()) {
            return Long.parseLong(matcher.group(1));
        }
        return null;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        player.release();
    }
}